\documentclass[11pt, oneside, hidelinks]{article}   	% use "amsart" instead of "article" for AMSLaTeX format
\usepackage{geometry}                		% See geometry.pdf to learn the layout options. There are lots.
\usepackage[portuguese]{babel}
\usepackage[utf8]{inputenc}
\geometry{letterpaper}                   		% ... or a4paper or a5paper or ... 
%\geometry{landscape}                		% Activate for for rotated page geometry
%\usepackage[parfill]{parskip}    		% Activate to begin paragraphs with an empty line rather than an indent
\usepackage{graphicx}				% Use pdf, png, jpg, or eps§ with pdflatex; use eps in DVI mode
\usepackage[export]{adjustbox}
\usepackage{lipsum}
\usepackage{hyperref}
\usepackage[font=small,labelfont=bf]{caption}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{natbib}
\usepackage[section]{placeins}
\usepackage{pdfpages}
\usepackage[nottoc,numbib]{tocbibind}

\bibpunct{(}{)}{;}{a}{,}{,}
\title{Ambiente de programação científica orientada a objetos NeoPZ: Uma introdução para novos alunos}
\author{Francisco T. Orlandini\\
LabMeC\\
UNICAMP\\
\\
Supervisionado por Nathan Shauer e Philippe Devloo
\\
francisco.orlandini@gmail.com}
\date{Outubro 2014}							% Activate to display a given date or no date




\begin{document}
\maketitle

\begin{abstract}
Neste tutorial buscamos apresentar de forma simples os conceitos fundamentais para um estudante ingressante no LabMeC, assim como algumas das ferramentas que virão a ser utilizadas no futuro. No decorrer de três meses é esperado que o aluno ambiente-se com a linguagem de programação C++, com o software Mathematica e com as ideias centrais em torno das quais se baseia o Método dos Elementos Finitos, além de uma visualização e experimentação inicial com o pacote NeoPZ.
\end{abstract}
\newpage
\tableofcontents
\newpage

\section{Introdução}
\subsection{Motivação}
Devido à grade dos cursos de graduação em Engenharia, é comum que o aluno ingressante no LabMeC não tenha conhecimento prévio na área em que virá a trabalhar. Este tutorial busca introduzir o aluno à ideia da implementação computacional do Método dos Elementos Finitos (FEM) distinguindo e esclarecendo os conceitos necessários para tal. 
\subsection{NeoPZ}
Atualmente, existem diversos de pacotes que implementam o FEM disponíveis no mercado, dentre eles podem ser citados \emph{Phoenix}, \emph{Ansys}, \emph{Sap2000}, \emph{FlexPDE}, \emph{Consol} e \emph{Hermes}, dentre outros. O uso do pacote NeoPZ faz-se interessante pois proporciona uma maior liberdade ao usuário, por exemplo, quanto à liberdade quanto à representação de geometrias arbitrárias - a aproximação de um círculo por um conjunto de segmentos de retas pode, por exemplo, influenciar bastante na simulação de problemas eletromagnéticos. Também permite a resolução de qualquer equação diferencial descrevendo um fenômeno físico, podendo então ser aplicado nas mais diversas áreas do conhecimento. Os diferenciais mais importantes do ambiente NeoPZ em relação aos outros pacotes são:
\begin{itemize}
\item Diversos espaços de aproximação  $H^{1}$, $L^{2}$, $H^{div}$, $H^{curl}$, podendo também o usuário definir o seu próprio espaço de aproximação.
\item Diversos métodos de resolução de Sistemas Lineares - Decomposição $LU$, $LDL^{t}$, Cholesky. Métodos iterativos como Gradiente conjugado, \emph{GMRES}, com ou sem pré-condicionador, dentre outros.
\item Compila em qualquer plataforma - Windows, Linux, OSX
\item HP adaptatividade em 1, 2 e 3D - Permite refinamento da malha somente onde este se faz necessário para obter uma melhor aproximação.
\end{itemize}

\begin{figure}[h!]
  \centering
      \includegraphics[width=1\textwidth]{figpz.png}
  \caption{Visão geral da arquitetura NeoPZ}
\end{figure}
\FloatBarrier
\subsection{Organização do tutorial e cronograma proposto}
As atividades propostas são divididas em quatro partes, e é esperado que o estudante leve três semanas para cada uma delas. Em caso de dificuldades, alguém do LabMeC deve ser avisado. A estrutura das partes é:
\begin{enumerate}
  \item Introdução a C++
  \item Introdução ao FEM
  \item Introdução ao \emph{Mathematica}
  \item Introdução ao pacote NeoPZ
\end{enumerate}
Na primeira parte é discutida a questão da programação orientada a objeto e a justificativa do emprego desta filosofia no pacote NeoPZ. Em seguida, são propostos dois pequenos exercícios para familiarizar o estudante com conceitos essenciais de C++.

Já na segunda parte, através da leitura de capítulos do livro Finite Elements: An Introduction Volume I \citep{oden81}, é esperado que o estudante adquira certa familiaridade com o FEM através da análise de problemas unidimensionais. Na terceira parte o estudante deve realizar dois exercícios utilizando o software Mathematica e aplicar os conceitos vistos na leitura dos capítulos do livro. Finalmente, na quarta parte o aluno tem uma primeira experiência com pacote NeoPZ, observando a simulação da mesma equação diferencial analisada nos capítulos lidos de \citet{oden81} e podendo comparar os resultados com os obtidos no Mathematica. 
\newpage

\section{Programação orientada a objeto e introdução a C++}
\subsection{Programação orientada a objeto}
Conforme explicado em \citet{deitel12}:\emph{``Objects, or more precisely[...], the classes objects come from, are essentially reusable software components. There are date objects, time objects, audio objects, video objects, automobile objects, people objects, etc. Almost any noun can be reasonably represented as a software object in terms of attributes (e.g., name, color and size) and behaviours (e.g., calculating, moving and communicating). Software developers are discovering that using a modular, object$-$oriented design and implementation approach can make software$-$development groups much more productive than was possible with earlier popular techniques like ``structured programming''$-$ object$-$oriented programs are often easier to understand, correct and modify.''}. Para uma maior compreensão dos paradigmas envolvidos na filosofia de programação orientada a objeto, é sugerida a leitura de \citet{eckel00}. O conceito de herança entre classes também é extensivamente utilizado no pacote NeoPZ.
\subsection{A linguagem de programação C++}
\subsection{Exercício}
\subsubsection{Ambientação}
\begin{itemize}
\item Criar um projeto novo em XCode 
\item Rodar o programa principal que ele mesmo criou 
\item Acrescentar uma função que realize a operação $f(x) = Sin(3\pi x) $ 
\item Imprimir o resultado para $0\leq x\leq \pi$ 
\item Executar o programa passo a passo utilizando o \emph{debugger}
\item Documentar um código utilizando Doxygen 
\end{itemize}
\subsubsection{Estudo prático da linguagem C++}
\subsubsection*{Classe Vetor}
Primeiramente, o aluno deve criar uma classe que implementa um vetor de números reais. No \emph{header} da classe, os objetivos da classe, assim como os de quaisquer métodos que venham a ser criados, devem estar bem explicados. A classe criada deve conter, pelo menos:
\begin{samepage}
\begin{itemize}
\item Construtor e destrutor 
\item Método que calcula a norma do vetor 
\item Métodos do tipo GetVal, SetVal 
\item Construtor de cópia 
\item Seleção de elemento através de operador [ ] 
\item Operador = 
\item Operador + e operador -
\item Operador ==
\end{itemize}
\emph{Obs: O livro \citet{deitel12} é fortemente recomendado para eventuais dúvidas, tanto relativas à sintaxe da linguagem quanto à ideia da classe em si}
\end{samepage}
\subsubsection*{Classe Matriz}
Em seguida, o aluno deve criar uma classe que implementa uma matriz. Obviamente, alguns dos métodos criados no exercício anterior podem vir a ser aproveitados (diretamente ou não). Os atributos e métodos necessários para a classe devem ser pensados pelo aluno, sendo livre a forma da implementação e as estruturas de dado envolvidas. Entretanto, assim como na classe de vetor, alguns objetivos devem ser cumpridos:
\newpage

\begin{itemize}
\begin{samepage}
\item A matriz deve ter elementos do tipo $REAL$ ( Ver $typedef$ em \citet{deitel12})
\item Construtor vazio;    
\item Construtor que cria uma matriz com $m$ linhas e $n$ colunas
\item Construtor de cópia
\item Destrutor
\item Método para redimensionamento da matriz ($Resize$)
\item Método que transpõe a matriz ($Transpose$)
\item Métodos do tipo $GetVal$ e $PutVal$
\item Operador () para seleção de elemento da matriz
\item Operador = para atribuição
\item Operador == para comparação
\item Operações de adição, subtração e multiplicação de matrizes (assim como seus respectivos operadores)
\item Operação do produto entre matriz e vetor
\item Uma função do tipo $debugStop()$
\end{samepage}
\end{itemize}
O aluno é incentivado a criar quaisquer métodos que venham a ser necessários para cumprir o objetivo. A classe deve ser testada com o auxílio de uma rotina que teste operações básicas possíveis de ser realizadas com ela. Ao final do exercício, o aluno deve rtesponder as seguintes questões:
\begin{enumerate}
  \item Qual o significado de $const$ após a assinatura de um método?
  \item Qual o significado de passar uma variável $const$ por referência?
  \item Quando são chamados os construtores e destrutores (\emph{Dica: utilizando a função std::cout, faça que os construtores e o destrutor de sua classe imprimam uma mensagem quando forem chamados e o endereço do objeto responsável pela sua chamada})?
  \item Existe utilidade dos métodos $GetVal$ e $PutVal$ se há o operador parênteses para seleção de elemento?
  \item Por que a utilização do $typedef\ double\ REAL;$?
\end{enumerate}
\newpage
\section{O Método dos Elementos Finitos (FEM): Uma introdução}
\subsection*{Introdução}
Nesta atividade, o aluno deve estudar o primeiro capítulo de \citet{oden81} e realizar os exercícios propostos no decorrer do capítulo. Caso haja interesse em se aprofundar no assunto, a subseção \ref{sub:oden2} sugere a leitura do segundo capítulo do livro e realça os pontos importantes.
\subsection{Oden - Capítulo I}
\label{sub:oden1}
No primeiro capítulo de \citet{oden81}, o FEM é apresentado através da análise de um problema chamado problema modelo. O problema modelo se trata de uma equação diferencial com solução analítica conhecida, para fins de análise e validação. Claramente, métodos numéricos não justificam o esforço computacional em casos assim, entretanto o exemplo é posto para fins didáticos. A Formulação fraca, ou forma variacional, é apresentada como uma forma de relaxamento das condições necessárias para uma solução satisfatória. Ao invés de nos contentarmos úica e somente com uma função $u(x)$.
  que satisfaça a equação diferencial em todos os pontos do domínio, buscamos agora uma função que satisfaça a nossa formulação fraca, ou seja, que satisfaça a nossa equação na forma integral. A nossa condição fraca também, naturalmente, diminui nossos critérios de suavidade quanto à solução desejada (na formulação variacional não aparece a segunda derivada da função $u(x)$
 ). É recomendada uma leitura atenta quanto aos espaços das funções $u(x)$  e $v(x)$ , dado que a discussão de qual é o espaço adequado para cada problema é de fundamental importância. 

Neste capítulo também é abordada a técnica de aproximação de Galerkin, e como ela nos permite restringir o espaço de funções no qual buscamos nossa aproximação através da criação de um subespaço N-dimensional do espaço de funções analisado, caracterizado por um conjunto infinito das chamadas funções de base. Finalmente, o FEM é apresentado como a aplicação da técnica de aproximação de Galerkin sobre a forma fraca do nosso problema aliado a um método sistemático para a escolha das funções de base, sendo o domínio dividido em regiões - chamadas de elementos - e as funções de base definidas individualmente sobre cada elemento. Uma aproximação para a solução analítica é então apresentada, com o uso de funções chapéu e a divisão do domínio em quatro elementos. Os exercícios que acompanham o texto são altamente recomendados. Na seção \ref{sec:math} deste tutorial o aluno deve realizar um programa no software Mathematica que permite a visualização dos procedimentos realizados neste capítulo.
\newpage
\subsection{Opcional: Oden - Capítulo II}
\label{sub:oden2}
Caso, neste momento, haja um interesse grande em minúcias das aplicações do FEM em problemas unidimensionais é recomendada a leitura do segundo capítulo do livro. Neste capítulo temos uma abordagem mais geral de problemas unidimensionais, dando-nos a capacidade para utilização do método em qualquer equação diferencial linear de segunda ordem, assim como maior detalhamento na implementação de um algoritmo utilizando o FEM. Após a apresentação da chamada forma clássica de uma equação diferencial de segunda ordem, o texto segue para uma análise cuidadosa dos tipos de condições de contorno, e como estas condições aparecerão na formulação fraca é essencial para a elaboração de um bom algoritmo - Além, naturalmente, de uma maior compreensão do método. Também é abordada neste capítulo a questão da escolha das funções de base, i.e., quais as restrições para que um determinado conjunto de funções seja um conjunto adequado para a representação de um espaço. Com o uso de funções Lagrangianas, neste capítulo é desenvolvido um raciocínio que permite o uso de funções de base de maior ordem, ao invés de somente as funções chapéu.

Quanto à parte computacional, é apresentado em maiores detalhes o conceito de assemblagem, que permite que os cálculos sejam feitos individualmente em cada elemento e depois posicionados adequadamente em uma matriz global. Este conceito permite, por exemplo, a paralelização de tarefas em um determinado estágio de um algoritmo que apresenta uma implementação do FEM. Assim como no Capítulo 1, os exercícios deste capítulo também são recomendados. Na subseção \ref{sub:math2} são sugeridas modificações no programa desenvolvido no Mathematica para fazer uso das técnicas apresentadas no Capítulo 2.
\newpage

\section{Introdução ao software Mathematica: Criando um primeiro código utilizando o FEM}
\label{sec:math}
\subsection*{Implementação do Problema Modelo}
Conforme abordado na subseção \ref{sub:oden1}, neste tutorial do Mathematica a proposta é de criar um algoritmo para a resolução numérica do problema modelo. Para isto, é necessário ter em mente tanto a equação diferencial que origina a forma fraca como as condições de contorno do problema em questão. Assim como no Capítulo 1 de \citet{oden81}, as funções de base escolhida serão lineares, as funções chapéu. Para melhor visualização da técnica, o algoritmo será feito de modo que o número de elementos em que o domínio será dividido seja variável, assim pode ser observada esta alteração no resultado final, quando comparado com a solução analítica.

\subsection{Implementação das funções chapéu}
As funções chapéu são elaboradas conforme o procedimento seguido no Capítulo 1 de \citet{oden81}, entretanto, desta vez criaremos um método geral para a divisão do domínio em qualquer número de elementos - todos com o mesmo comprimento. Assim sendo, como nosso domínio é a reta $0\leq x \leq1$, se tivermos $nel$ elementos, cada um terá comprimento $h=\frac{1}{nel}$. Tendo em vista um nó interno $x_{i}$ ao nosso domínio - i.e., excluindo os nós de fronteira, podemos dizer que a função de base correspondente será definida por $\frac{x-(x_{i}-h)}{h},x_{i}-h \leq x\leq x_{i}$ e $\frac{x_{i}+h-x}{h},x_{i}\leq x \leq x_{i}+h$, tendo valor nulo para qualquer outro valor de $x$. Na Figura \ref{fig:Funcoes-de-forma-Math-1}, vemos as funções de formas geradas ao dividirmos o domínio em 4 elementos (pode-se verificar que o resultado é idêntico ao apresentado em \citet{oden81}). O Mathematica apresenta também a função \emph{D[f,x]}, que a realiza a derivada de $f$ em relação a $x$, e esta pode ser útil mais adiante no cálculo dos elementos da matrix $K$ e do vetor $F$.
\begin{figure}[h!]
  \centering
      \includegraphics[width=0.5\textwidth]{fig1.png}
  \caption{Funções de forma geradas pelo \emph{software} Mathematica}
  \label{fig:Funcoes-de-forma-Math-1}
\end{figure}

\subsection{Implementação das Estruturas de Dados}
Nesta versão do algoritmo, tanto a Matriz de Rigidez quanto o Vetor de Carga serão computados de uma só vez, ao invés da soma das matrizes (ou vetores, no caso do vetor de carga) locais de cada elemento, apenas para fins de simplificação do algoritmo. Assim sendo, a função Table do Mathematica pode ser utilizada para criá-los. A função MatrixForm permite a visualização da matriz ou vetor passada como parâmetro na forma matricial, como pode ser visto na Figura \ref{fig:math1matriz}.
\begin{figure}[h!]
  \centering
      \includegraphics[width=0.4\textwidth]{fig2.png}
  \caption{Matriz de Rigidez (K) e Vetor de Carga (F) gerados pelo algoritmo e visualizadas através do comando \emph{MatrixForm}.}
  \label{fig:math1matriz}
\end{figure}

\subsection{Resolução do Problema}
Após obter a matriz $K$ e o vetor $F$, o comando \emph{LinearSolve} pode ser utilizado para resolver o sistema e encontrar os coeficientes (no caso de 4 elementos, confira-os com os coeficientes obtidos em \citet{oden81}). Lembrando que a aproximação é calculada a partir da somatória das multplicações de $\alpha_{j}\phi_{j}$ , o comando \emph{Plot} pode ser utilizado para visualizar, por exemplo, a comparação da aproximação com a solução analítica do problema, como pode ser visto na figura \ref{fig:plotmath1}.
\begin{figure}[h!]
  \centering
      \includegraphics[width=0.4\textwidth]{fig3.png}
  \caption{Comparação da aproximação obtida com a solução analítica.}
  \label{fig:plotmath1}
\end{figure}

\subsection{Opcional: Implementação de Funções Lagrangianas}
\label{sub:math2}
Nesta seção o aluno deve implementar um algoritmo mais generalizado da resolução do problema modelo através do FEM. Baseado fortemente no algoritmo anterior, desta vez alterações devem ser feitas de modo que a computação da matriz de rigidez e do vetor de carga seja feita separadamente para cada elemento - e depois seja implementado o processo de \emph{assemblagem}, no qual cada matriz local é alocada na matriz global. Além disso, também é interessante a opção de que as funções de base a serem utilizadas desta vez sejam funções lagrangianas de ordem a ser especificada pelo usuário. Por mais que rotineiramente o uso de funções lagrangianas seja bastante diminuto comparado ao uso de funções hierárquicas, essas permitem ao aluno uma visão bastante clara da influência da ordem dos polinômios das funções de base.
\subsubsection{Elemento mestre}
Conforme explicado no capítulo 2 do livro de \citet{oden81}, todas as computações serão realizadas no chamado Elemento Mestre. Com o uso da coordenada generalizada $\xi$, cada elemento será mapeado de modo que, se o elemento i é delimitado pelos nós $x_{i}$ e $x_{i+1}$, estes pontos serão mapeados, respectivamente, nos pontos $\xi=-1$ e $\xi=+1$. As funções de forma serão definidas no domínio de $\xi$, e através da matriz de dependência, serão relacionadas às funções de base globais correspondentes (este processo será descrito em detalhes na subseção \ref{sub:assemblagem}). Como deve estar claro neste ponto, as integrais também serão realizadas no domínio $\xi=[-1,1]$, e portanto obteremos, por exemplo, para a matriz de rigidez local:
\centerline{$Kel_{j,k}=\int_{x[i]}^{x[i+1]}[\phi_{j}(x)\phi_{k}(x)+\frac{d\phi_{j}(x)}{dx}\frac{d\phi_{k}(x)}{dx}]dx$}
\centerline{$=\int_{-1}^{1}[\psi_{j}(\xi)\psi_{k}(\xi)+\frac{d\psi_{j}(\xi)}{d\xi}\frac{d\xi}{dx}\frac{d\psi_{k}(\xi)}{d\xi}\frac{d\xi}{dx}]\frac{d\xi}{dx}^{-1}d\xi$}

\subsubsection{Funções de Forma Lagrangianas}x
As funções de forma utilizadas no algoritmo devem ser lagrangianas. Conforme definidas no Capítulo 2 de \citet{oden81}, se deseja-se utilizar funções de ordem $p$ e da subdivisão do elemento obtém-se $p+1$  pontos equidistantes $x_{i},i=1,2,...,p+1$(que são mapeados no domínio $\xi$) as funções de forma são, portanto:

\centerline{$\psi_{i}(\xi)=\prod_{j=1,j\neq i}^{p+1}\frac{\xi-\xi_{j}}{\xi_{i}-\xi_{j}}$} 

Com a propriedade de: 
		
 \centerline{$\psi_{i}(\xi_{j})	=\begin{cases} 
 1, & j=i\\ 
 0, & j\neq i
 \end{cases}	$}		
 \subsubsection{Assemblagem}
 \label{sub:assemblagem}
 Assemblagem é o processo de posicionar corretamente as matrizes locais geradas na computação individual de cada elemento na matriz global. Isso equivale a associar cada função de forma (definidas no elemento mestre, portanto, em $\xi$) à função de base equivalente( definida no domínio do problema, portanto, em $x$). Assim, se temos $nel$ elementos e $p+1$ funções de forma, nossa matriz de dependência terá $nel$ linhas e $p+1$ colunas, sendo o elemento $[dependencyMatrix]_{i,j}$  a função de base associada à j-ésima função de forma do elemento i. No caso de funções lagrangianas, é bom lembrar que a primeira função de forma do elemento $i+1$ corresponde à mesma função de base do que a última função de forma do elemento i, portanto, elas devem ter o mesmo coeficiente $\alpha_{j}$ associado a elas, \emph{i.e.}, o mesmo grau de liberdade.
 \begin{figure}[h!]
  \centering
      \includegraphics[width=0.4\textwidth]{fig4.png}
  \caption{Matriz de dependência gerada no caso da divisão do domínio em dez elementos e funções de forma de segundo grau.}
  \label{fig:dependencymatrix}
\end{figure}

\subsubsection{Condições de Contorno}
No caso de condições de contorno de Dirichlet (Ver seção 2.7.4 de \citet{oden81}), queremos forçar, por exemplo, $\alpha_{1}=v_{1}$. Temos $\alpha_{1}K_{1,1}+\alpha_{2}K_{1,2}+...+\alpha_{N}
K_{1,N}=F_{1}$ (onde $N=nel*p+1$), portanto,  fazendo $F_{1}=v_{1}*BIG$ e $K_{1,1}=BIG$ , onde $BIG\gg1$ forçamos $\alpha_{1}=\frac{F_{1}-(\alpha_{2}K_{1,2}+...+\alpha_{N}K_{1,N})}{K_{1,1}}=v_{1}$. O mesmo raciocínio pode ser ser utilizado para impor um valor para $\alpha_{N}$.
%No caso de condições de contorno de Dirichlet (Ver seção 2.7.4 de \citet{oden81}), queremos forçar $\alpha_{1}=\alpha_{nel\ast p+1}=$. Temos $\alpha_{1}K_{1,1}+\alpha_{2}K_{1,2}+...+\alpha_{N}%K_{1,N}=F_{1}$ (onde $N=nel*p+1$), portanto,  fazendo $F_{1}=0$ e $K_{1,1}\gg1$ , forçamos $\alpha_{1}=\frac{F_{1}-(\alpha_{2}K_{1,2}+...+\alpha_{N}K_{1,N})}{K_{1,1}}=0$. O mesmo raciocínio %pode ser ser utilizado para $\alpha_{N}$.
  \begin{figure}[h!]
  \centering
      \includegraphics[width=0.7\textwidth]{fig5.png}
  \caption{Funções de base multiplicadas pelos seus respectivos coeficientes, gerados no caso da divisão do domínio em dez elementos e funções de forma de segundo grau. A aproximação obtida corresponde à soma destas funções.}
  \label{fig:basisfunctions}
\end{figure}
\newpage
\section{O pacote NeoPZ e a implementação do Problema Modelo}
Nesta seção o aluno deve instalar o Pacote NeoPZ, rodar uma simulação já implementada e analisar seu algoritmo, visando a ambientação com o pacote.
\subsection{Dependências}
Para a instalação do pacote NeoPZ, siga o tutorial encontrado no site do \cite{website:labmec} em \url{http://www.labmec.org.br/wiki/howto/start}.
\subsection{Exemplo Simples}
Após a instalação do pacote NeoPZ o aluno deve executar o programa \emph{ExemploSimples.cpp}, no qual é implementado o Problema Modelo do primeiro capítulo de \citet{oden81} com número variável de elementos. O aluno deve então ler o código, entendendo cada linha deste, para se ambientar com o ambiente NeoPZ - inclusive o material criado para este exemplo, \emph{TPZMatModelProblem}, que implementa a formulação fraca do problema modelo. Entretanto, um aviso: Não é esperado que o aluno compreenda todas as estruturas de dados utilizadas no NeoPZ para a resolução de um problema, somente a estrutura de dados de forma geral, apresentada nos arquivos \emph{ExemploSimples.cpp}, \emph{TPZMatModelProblem.h} e  \emph{TPZMatModelProblem.cpp}. Após a execução do programa, será gerado um arquivo \emph{.vtk} que poderá ser visualizado utilizando o software \emph{Paraview}, e também será gerada no próprio console de execução a saída na formatação compatível com o Mathematica, para fins de comparação. É esperado que o aluno verifique se foram obtidos os mesmos resultados obtidos na seção \ref{sec:math}.
\newpage
\bibliographystyle{plainnat}
\bibliography{bibliografia}
\newpage
\appendix
\section{Phillipe R. B. Devloo - Simulação Numérica}\label{app:devloo}
\includepdf[pages=-]{Devloo_Simulacao.pdf}
\end{document}
